package com.gagakuai.demo.registrytest;

import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.*;

/*
 * @program: settement
 * @description:
 * @author: houhong
 * @create: 2022-11-12 18:13
 */
@Component
public class ServiceBeanDefinitionRegistryPostProccessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

    }

    @SneakyThrows
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        //实列化 出依赖注入的Bean 这里还需要放在AbstactBeanFacotory中的List<BeanPostProcessor>中
        BeanPostProcessor autowirdPostProcessor = (AutowiredAnnotationBeanPostProcessor) beanFactory.getBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME);
        beanFactory.addBeanPostProcessor(autowirdPostProcessor);
        BeanPostProcessor resourcePostProcessor = (CommonAnnotationBeanPostProcessor) beanFactory.getBean(AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME);
        beanFactory.addBeanPostProcessor(resourcePostProcessor);

        List<String> testList = new ArrayList<>();
        testList.add("1");
        testList.add("2");
        testList.add("3");
        Map<String, AbstractService> handlerMap = new HashMap<>();
        for (String s : testList) {
            AbstractService abstractService = getBeansWithAnnotation(beanFactory, AbstractService.class, ServiceTyp.class,
                    s);
            handlerMap.put(s, abstractService);
        }
        ServiceContext context = new ServiceContext(handlerMap);
        //单例注入
        beanFactory.registerSingleton(ServiceContext.class.getName(), context);

    }

    /*
     * 通过父类+注解找到实体类
     */
    private <T> T getBeansWithAnnotation(ConfigurableListableBeanFactory beanFactory, Class<T> manager, Class<? extends ServiceTyp> annotation, String code) throws BeansException {
        if (ObjectUtils.isEmpty(code)) {
            throw new RuntimeException("code is null ");
        }
        Collection<T> tCollection = beanFactory.getBeansOfType(manager).values();
        for (T t : tCollection) {

            ServiceTyp mainBoardTaskType = t.getClass().getAnnotation(annotation);
            if (ObjectUtils.isEmpty(mainBoardTaskType)) {
                throw new RuntimeException("该注解没有写入值 :" + code);
            }
            //注解值是否与code相等
            if (code.equals(mainBoardTaskType.value())) {
                return t;
            }
        }
        throw new RuntimeException("通过code没有找到该注解对应的实体类 :" + code);
    }
}